﻿namespace TouchPoint.Text
{
    using System;
    using System.Text;

    public sealed class TextContent
    {
        private readonly RopeNode _root;
        private int _length;

        public TextContent()
        {

        }

        public TextContent(string str)
        {

        }

        #region Rope

        //---------------------------------------------------------------------------------------------------
        //  Rope数据结构是一棵二叉树，它的每个节点都有一个权值，该权值对于非叶子结点而言是所有左子树权值之和，对于叶子结点而言
        //  是其保存的字符串长度
        //---------------------------------------------------------------------------------------------------

        private char Index(RopeNode node, int i)
        {
            if (node.Weight <= i) {
                return Index(node.Right, i - node.Weight);
            }
            else {
                if (node.Left != null) {
                    return Index(node.Left, i);
                }
                else {
                    return node.Value[i];
                }
            }
        }


        //---------------------------------------------------------------------------------------------------
        //
        //                          Concat
        //                                                   Q
        //         C                 G                    /     \
        //       /   \      +      /   \       =>       C         G
        //     E       F         J       K            /   \     /    \
        //                                          E       F  J       K
        //
        //      Rope Node1       Rope Node2             Rope newNode
        //---------------------------------------------------------------------------------------------------
        private RopeNode Concat(RopeNode node1, RopeNode node2)
        {

            //---------------------------------------------------------------------------------------------------
            //  Concatenation
            //  在一般情况下，连接操作声明一个包含两个需要进行连接操作的节点作为参数的简单关联节点。出于性能考虑，
            //  我们期望右参数节点是一个短纯文本字符串。如果两个节点均为短叶子节点
            //---------------------------------------------------------------------------------------------------
            if(node1.IsLeafNode && node2.IsLeafNode) {
                return null;
            }
            else {
                RopeNode newNode = new RopeNode
                {
                    Left = node1,
                    Right = node2
                };
                return newNode;
            }
            
        }

        private void Delete(RopeNode node, int start, int length)
        {

        }

        private void Split(RopeNode node, char deliver)
        {

        }

        /// <summary>
        /// 计算左子树的权值
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        static int ComputeLeftSubTree(RopeNode node)
        {
            if (node == null) {
                return 0;
            }
            else if (node.IsLeafNode) {
                return node.Value.Length;
            }
            else {
                return ComputeLeftSubTree(node.Left) + ComputeLeftSubTree(node.Right);
            }
        }

        sealed class RopeNode
        {           
            public char[] Value { get; set; }

            //---------------------------------------------------------------------------------------------------
            //  Rope计算权值的方法:
            //  1.叶子结点:             该节点保存的字符串长度
            //  2.左孩子为叶子结点:       返回左孩子的权值
            //  3.左孩子为非叶子节点:     计算左子树的权值
            //---------------------------------------------------------------------------------------------------
            public int Weight {
                get {
                    if (this.IsLeafNode) {
                        return this.Value.Length;
                    }
                    else {
                        if (Left.IsLeafNode) {
                            return this.Left.Weight;
                        }
                        else {
                            return ComputeLeftSubTree(this.Left);
                        }
                    }
                }
            }

            public RopeNode Left { get; set; }

            public RopeNode Right { get; set; }

            public bool IsLeafNode {
                get {
                    return Left == null && Right == null;
                }
            }
        }

        #endregion

        #region String Method

        /// <summary>
        /// 将指定的字符附加到文本尾部
        /// </summary>
        /// <param name="str"></param>
        public void Append(string str)
        {
            // TODO:Append Method Implement
            
        }

        /// <summary>
        /// 将指定文本内容与当前文本内容拼接
        /// </summary>
        /// <param name="text">指定要拼接到尾部的文本内容</param>
        /// <returns>返回拼接后的文本内容</returns>
        public TextContent Concat(TextContent text)
        {
            // TODO: Concat Method Implement
            return null;
        }

        public TextContent Replace(string oldValue,string newValue)
        {
            // TODO: Replace Method Implement
            return null;
        }

        public TextContent SubString(int index,int length)
        {
            // TODO: SubString Method implement
            return null;
        }

        public bool Contains(string str)
        {
            // TODO:
            throw new NotImplementedException();
        }

        public int IndexOf(char ch)
        {
            throw new NotImplementedException();
        }

        public int LastIndexOf(char ch)
        {
            throw new NotImplementedException();
        }


        public string GetString(int index,int offset,int length)
        {
            return string.Empty;
        }

        #endregion

        #region Property & Indexer

        /// <summary>
        /// 获取当前文本内容的长度
        /// </summary>
        public int Length {
            get {
                return _length;
            }
        }

        /// <summary>
        /// 索引当前文本内容
        /// </summary>
        /// <param name="index">指定的索引位置</param>
        /// <returns>返回指定索引位置的字符</returns>
        public char this[int index] {
            get {
                if (index < 0 || index > _length) {
                    throw new IndexOutOfRangeException();
                }

                return Index(_root, index);
            }
        }

        #endregion
    }
}
